package com.hyfd.deal.Bill;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hyfd.common.GenerateData;
import com.hyfd.common.utils.DateTimeUtils;
import com.hyfd.common.utils.MD5;
import com.hyfd.common.utils.MapUtils;
import com.hyfd.common.utils.RSAEncrypt;
import com.hyfd.common.utils.ToolHttp;
import com.hyfd.common.utils.XmlUtils;
import com.hyfd.deal.BaseDeal;

public class HaiHangBillDeal implements BaseDeal{

	Logger log = Logger.getLogger(getClass());
	
	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> deal(Map<String, Object> order) {
		Map<String,Object> map = new HashMap<String,Object>();
		int flag = -1;
		try{
			String phone = (String) order.get("phone");//手机号
			double fee = (double) order.get("fee");//金额，以元为单位
			String curids = DateTimeUtils.formatDate(new Date(), "yyyyMMddHHmmssSSS") + phone+GenerateData.getIntData(9, 6);
			String reqTime = DateTimeUtils.formatDate(new Date(), "yyyyMMddHHmmss");
			map.put("orderId", curids);
			Map<String,Object> channel = (Map<String, Object>) order.get("channel");//获取通道参数
			String linkUrl = (String) channel.get("link_url");//充值地址
			String defaultParameter = (String) channel.get("default_parameter");//默认参数
			Map<String,String> paramMap = XmlUtils.readXmlToMap(defaultParameter.trim());
			String SysId = paramMap.get("SysId");//系统编码
			String StaffId = paramMap.get("StaffId");//充值工号
			String Type = paramMap.get("Type");//操作类型
			String PayAcct = paramMap.get("PayAcct");//代理商账户
			String Pwd = paramMap.get("Pwd");//代理商密码
			String RequestSource = paramMap.get("RequestSource");//自服务平台标识
			String RequestUser = paramMap.get("RequestUser");//登录用户名
			String DestinationAttr = paramMap.get("DestinationAttr");//被充值用户属性
			String DestinationAttrDetail = paramMap.get("DestinationAttrDetail");//被充值用户属性明细
			String ObjType = paramMap.get("ObjType");//号码类型
			String BalanceType = paramMap.get("BalanceType");//余额类型
			String ServiceCode = paramMap.get("ServiceCode");//服务编码
			String RechargeUnit = paramMap.get("RechargeUnit");//充值金额单位0分1条
			String RechargeType = paramMap.get("RechargeType");//充值类型0快充1卡充默认值 0
			String yekUrl = paramMap.get("yekUrl");//请求地址
			//发送充值请求
			String responseXml = sendPost(linkUrl, curids, ServiceCode, reqTime, SysId, Type, PayAcct, Pwd, RequestSource, RequestUser, curids, reqTime, phone, DestinationAttr, DestinationAttrDetail, ObjType, BalanceType, RechargeUnit, fee+"", RechargeType, StaffId);
			JSONObject responseJson = readXmlToJson(responseXml);
			if(responseJson!=null){
				String resultCode = responseJson.getJSONObject("SvcCont").getJSONArray("SOO").getJSONObject(0).getJSONObject("RESP").getString("Result");
				map.put("resultCode", resultCode);
				if(resultCode.equals("0")){//提交成功
					flag = 1;
				}else{//提交失败
					flag = 0;
				}
			}
		}catch(Exception e){
			log.error("海航话费充值出错"+e.getMessage()+"|||"+MapUtils.toString(order));
		}
		map.put("status", flag);
		return map;
	}

	/**
	 * 
	 * @param url
	 * @param transactionID
	 *          事务标识，由发起端生成
	 * @param serviceCode
	 *          服务编码，唯一标识服务，必填字段
	 * @param reqTime
	 *          请求时间，格式：yyyymmddhh24miss
	 * @param sysId
	 *          发送请求的系统标识，与SvcCont（报文体）中可能出现的EXT_SYSTEM、SYSTEM_ID、
	 *          SystemID等字段含义保持一致，取值也应保持一致，具体取值参考附录。
	 *          PUB_RES：操作资源，一个包体中可能包含多个操作，可合为一个请求发送
	 * @param type
	 *          操作类型，标记具体的接口操作方法
	 * @param payAcct
	 *          代理商账号
	 * @param pwd
	 *          代理商密码 ，需要加密
	 * @param requestSource
	 *          自服务平台标识或IP地址
	 * @param requestUser
	 *          用户如果登录填写登录用户名，
	 * @param requestId
	 *          请求流水
	 * @param requestTime
	 *          请求时间，YYYYMMDDHHMMSS
	 * @param destinationId
	 *          被充值用户号码
	 * @param destinationAttr
	 *          被充值用户属性（取值参见省间互联分册7.5.53）
	 * @param destinationAttrDetail
	 *          被充值用户属性明细（取值参见省间互联分册7.5.79）
	 * @param objType
	 *          号码类型，1：帐户；2：客户；3：用户；
	 * @param balanceType
	 *          余额类型，根据各地情况分别定义
	 * @param rechargeUnit
	 *          充值金额单位：0－分；1－条;
	 * @param rechargeAmount
	 *          充值金额
	 * @param rechargeType
	 *          充值类型，0快充，1卡充，默认值 0
	 * @param staffId
	 *          员工标识
	 */

	public static String sendPost(String url, String transactionID, String serviceCode, String reqTime, String sysId, String type, String payAcct, String pwd, String requestSource, String requestUser, String requestId, String requestTime, String destinationId, String destinationAttr, String destinationAttrDetail, String objType, String balanceType, String rechargeUnit, String rechargeAmount,
			String rechargeType, String staffId) {
		StringBuffer xml = new StringBuffer();
		xml.append("<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:ns1=\"http://www.tydic.com/\"><SOAP-ENV:Header/><SOAP-ENV:Body><Business>");
		JSONObject jsonObject = new JSONObject(true);
		JSONObject tcpCont = new JSONObject();
		JSONObject svcCont = new JSONObject();
		JSONArray SOOArray = new JSONArray();
		JSONObject SOO = new JSONObject();
		JSONObject PUBREQ = new JSONObject();
		PUBREQ.put("TYPE", type);// Recharge
		SOO.put("PUB_REQ", PUBREQ);
		svcCont.put("SOO", SOOArray);
		JSONObject RECHARGEREQ = new JSONObject(true);
		RECHARGEREQ.put("BalanceType", balanceType);
		RECHARGEREQ.put("DestinationAttr", destinationAttr);
		RECHARGEREQ.put("DestinationAttrDetail", destinationAttrDetail);
		RECHARGEREQ.put("DestinationId", destinationId);
		RECHARGEREQ.put("ObjType", objType);
		RECHARGEREQ.put("PayAcct", payAcct);
		RECHARGEREQ.put("Pwd", MD5.ToMD5(pwd));
		RECHARGEREQ.put("RechargeAmount", rechargeAmount);
		RECHARGEREQ.put("RechargeType", rechargeType);
		RECHARGEREQ.put("RechargeUnit", rechargeUnit);
		RECHARGEREQ.put("RequestId", requestId);
		RECHARGEREQ.put("RequestSource", requestSource);
		RECHARGEREQ.put("RequestTime", requestTime);
		RECHARGEREQ.put("RequestUser", requestUser);
		RECHARGEREQ.put("StaffId", staffId);
		SOO.put("RechargeReq", RECHARGEREQ);
		SOOArray.add(SOO);
		RSAEncrypt rsaEncrypt = new RSAEncrypt();
		// 先进行MD5加密需要签名的字符串
		String code = rsaEncrypt.MD5(JSONObject.toJSONString(svcCont));
		// 把MD5加密内容通过私钥签名
		String signatureInfo = rsaEncrypt.enc(code);

		tcpCont.put("TransactionID", transactionID);
		tcpCont.put("ReqTime", reqTime);
		tcpCont.put("SignatureInfo", signatureInfo);
		tcpCont.put("ServiceCode", serviceCode);
		tcpCont.put("SYS_ID", sysId);
		jsonObject.put("TcpCont", tcpCont);
		jsonObject.put("SvcCont", svcCont);
		xml.append(jsonObject);
		xml.append("</Business></SOAP-ENV:Body></SOAP-ENV:Envelope>");

		String ret = "";
		try {
			ret = ToolHttp.post(true, url, xml.toString(), null);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ret;
	}
	
	/**
	 * 将xml字符串转换成Json(给上游发送请求，有数据返回时调用)
	 * 
	 * @param xml
	 *          发送充值请求后，上游返回的xml
	 */
	public static JSONObject readXmlToJson(String xml) {
		Document doc = null;
		Map<String, String> map = new HashMap<String, String>();
		try {
			doc = DocumentHelper.parseText(xml); // 将字符串转为XML
			Element rootElt = doc.getRootElement(); // 获取根节点
			List l = rootElt.elements();
			Element body = rootElt.element("Body");
			String jsonStr = body.elementTextTrim("Business");

			JSONObject json = JSONObject.parseObject(jsonStr);

			return json;

		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("解析出錯");
		return null;
	}
}
